package com.endurance.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;


/**
 * 这个类作为Spring的配置类，来取代Spring的配置文件
 */

// 代表这是一个spring配置类
@Configuration
// 替代：<context:component-scan base-package="com.endurance"></context:component-scan>
@ComponentScan("com.endurance")
// 替代：<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
@PropertySource("classpath:db.properties")
public class SpringConfig {

    // 替代： <property name="xxx" value="${xxx}"></property>
    @Value("${db.driver}")
    private String driverClassName;
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String username;
    @Value("${db.password}")
    private String password;


    /**
     * 用于返回实例的方法上, 相当于将方法的返回值定义为一个Bean，返回的对象交给Spring去管理,方便注入
     * 替代：
     *     <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
     *         <property name="driverClass" value="${db.driver}"></property>
     *         <property name="jdbcUrl" value="${db.url}"></property>
     *         <property name="user" value="${db.username}"></property>
     *         <property name="password" value="${db.password}"></property>
     *     </bean>
     */
    @Bean("dataSource") // 相当于Bean的id属性
    public DataSource initDataSource() {
        /**
         * 新建dbcp2，并设置链接信息
         */
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        try {
            comboPooledDataSource.setDriverClass(driverClassName);
            comboPooledDataSource.setJdbcUrl(url);
            comboPooledDataSource.setUser(username);
            comboPooledDataSource.setPassword(password);
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e);
        }
        return comboPooledDataSource;
    }

    /**
     *  将QueryRunner指定为多例,可以防止多线程安全问题,便于事务管理
     * 替代：
     *     <bean class="org.apache.commons.dbutils.QueryRunner" id="queryRunner">
     *         <!--通过构造器注入数据源-->
     *         <constructor-arg name="ds" ref="dataSource"></constructor-arg>
     *     </bean>
     */
    @Bean("queryRunner") // 相当于Bean的id属性
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public QueryRunner initDataSource(DataSource dataSource /*会自动注入的*/) {
        return new QueryRunner(dataSource);
    }



}
